﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace OpenShape
{
    public partial class ClusterAnaly : Form
    {

        #region == 초기변수선언부 ==

        CStatics.ACluster CSAC;
        public string[] Idx;
        DataTable dt;
        public int RowCount = 0;
        public string[] Rowarry = null;
        public string[,] CC_Group = null;

        public string[,] RowIdxArry = null;  // 정우
        public int FuncLoop = 0;  // 정우
        public bool booltest = true;
        #endregion


        public ClusterAnaly(DataTable odt)
        {
            InitializeComponent();
            this.dt =  odt;
            RowCount = dt.Rows.Count;
            //CStatics.AnalyDBF = "oo5/oo6/oo7/oo8/oo9/o10/oo4";   // 샘플데이터 필드 입력과정 없이 실행용
            Idx = SplitStr(CStatics.AnalyDBF.ToString());

            CSAC = new CStatics.ACluster(Idx);

            Rowarry = new string[RowCount];
            RowIdxArry = new string[RowCount, RowCount];  // 정우
            CC_Group = new string[RowCount, 2];
            Form_Load();
        }

       public void Form_Load()
        {
            // 기초 자료 분석 : 평균 -> 분산 -> Z-Score -> 변수간 거리
            CSAC.Analy1(dt);

           // 변수간 거리 데이터를 분석용 자료에 대입
            double[,] loop_array = CSAC.dis_Analysis;

            #region 분석용 원본 자료 출력 테스트 

            //테스트
            if (booltest)
            {
                dg6.ColumnCount = Convert.ToInt32(Math.Sqrt(loop_array.Length));
                for (int i = 0; i < Math.Sqrt(loop_array.Length); i++)
                {
                    string[] temp_array = new string[Convert.ToInt32(Math.Sqrt(loop_array.Length))];
                    for (int j = 0; j < Math.Sqrt(loop_array.Length); j++)
                    {
                        temp_array[j] = loop_array[i, j].ToString();
                    }
                    dg6.Rows.Add(temp_array);
                }
            }
            //  ==== 테스트 끝 ======
            #endregion 테스트

            // RowIdxArry에 분석용 자료의 위치와 동일 위치에 dt의 rows의 인덱스값 대입
            for (int i = 0; i < RowCount; i++)  //정우
			{
			 RowIdxArry[0,i] = i.ToString();
			}

           // 변수간의 거리를 통한 군집 생성 - 재귀호출
            Fnc_ArrayZero2(loop_array);  // 정우   
            Fnc_Show_Cluster(5);
        }

       public void Fnc_Show_Cluster(int NG)
       {
           int Group_Number = NG;

           for (int i = 0; i < Group_Number; i++)
           {
               string T_String = RowIdxArry[RowCount-Group_Number, i].Replace("/", "");
               string[] T_String_Array = T_String.Split(',');

               for (int j = 0; j < T_String_Array.Length; j++)
               {
                   CC_Group[Convert.ToInt32(T_String_Array[j]), 0] = dt.Rows[Convert.ToInt32(T_String_Array[j])][Convert.ToInt32(Idx[Idx.Length - 1])].ToString();
                   CC_Group[Convert.ToInt32(T_String_Array[j]), 1] = i.ToString();
               }

           }

           o_dg.ColumnCount = 2;
           for (int i = 0; i < RowCount; i++)
           {
               string[] temp_array = new string[2];
               for (int j = 0; j < 2; j++)
               {
                   temp_array[j] = CC_Group[i, j].ToString();
               }
               o_dg.Rows.Add(temp_array);
           }

       }

       public void Fnc_ArrayZero2(double[,] SourceArry)
        {
            int NewArryRow = 0;
            int SourceArryRow = 0;
            int[] MaxIJ = new int[2];
            double MaxValue = 0;

            FuncLoop = FuncLoop + 1;
            
            SourceArryRow = Convert.ToInt32(Math.Sqrt(SourceArry.Length));
            NewArryRow = SourceArryRow - 1;

            if (NewArryRow > 0)  // 원값은 0
                {
                ArryMaxVal(SourceArry, out MaxIJ, out MaxValue);

                #region 군집의 최고 상관값 테스트 출력용
                
                if (booltest)
                {
                    listBox3.Items.Add(MaxValue.ToString());
                }
                #endregion
                // =====  RowIdx 저장 시작
                int h = 0;
                for (int i = 0; i < SourceArryRow; i++)
                {
                    if (i != MaxIJ[0] && i != MaxIJ[1])
                    {
                        RowIdxArry[FuncLoop, h] = RowIdxArry[FuncLoop-1, i];
                        h += 1;
                    }
                }
                RowIdxArry[FuncLoop, h] = RowIdxArry[FuncLoop - 1, MaxIJ[0]] + "," + RowIdxArry[FuncLoop - 1, MaxIJ[1]] + "/";

                #region 군집자료 확인 테스트 구문
               
                if (booltest)
                {
                    string temp_string = "";
                    for (int i = 0; i < NewArryRow; i++)
                    {
                        temp_string += RowIdxArry[FuncLoop, i] + " |  ";
                    }
                    listBox5.Items.Add(temp_string);
                }
                #endregion
                // =====  RowIdx 저장 끝

                double[,] NewArry = new double[(int)NewArryRow, (int)NewArryRow]; // 5.5
              
                int n = 0;

                for (int i = 0; i < SourceArryRow; i++)
                {
                    if (i != MaxIJ[0] && i != MaxIJ[1])
                    {
                        int m = 0;
                        for (int j = 0; j < SourceArryRow; j++)
                        {
                            if (j != MaxIJ[0] && j != MaxIJ[1]) // 최고값의 i,j 아닌값 새 배열에 넣기
                             {
                                 if (j < i) // 대각선 아래값처리
                                 {  NewArry[n, m] = -99;  }
                                 else //대각선위 , 값처리
                                 {  NewArry[n, m] = SourceArry[i, j];  }
                                 m += 1;
                             }  //if (j != max_value[0]
                        } // for (int j

                        // ==============  i또는j 가 최고값의 i,j일때 [i,j]> [j,i] 판단 시작
                        double temp_MaxIJ0 = 0;
                        double temp_MaxIJ1 = 0;

                        temp_MaxIJ0 = SourceArry[i, MaxIJ[0]];
                        if (temp_MaxIJ0 == -99)
                            { temp_MaxIJ0 = SourceArry[MaxIJ[0], i]; }

                        temp_MaxIJ1 = SourceArry[i, MaxIJ[1]];
                        if (temp_MaxIJ1 == -99)
                            { temp_MaxIJ1 = SourceArry[MaxIJ[1], i]; }

                        if (temp_MaxIJ0 < temp_MaxIJ1) 
                            {  NewArry[n, m] = temp_MaxIJ0;   }
                        else
                            {  NewArry[n, m] = temp_MaxIJ1;   }

                        // ==============   i또는j 가 최고값의 i,j일때 [i,j]> [j,i] 판단 끝
                        n += 1;
                    }  // if (i != MaxIJ[0] && i != MaxIJ[1]) 것
                } //  for i

                // =============  분석결과 배열의 마지막 줄의 값을 입력 시작     ========
                for (int j = 0; j < NewArryRow; j++)
                {
                    if (j == n)
                    {   NewArry[n, j] = 1;  }
                    else
                    {   NewArry[n, j] = -99;  }
                }
                // =============  분석결과 배열의 마지막 줄의 값을 입력 끝     ========

                #region 최종 1~4번 분석 결과 출력 테스트 루팅
                // 테스트 루팅========================
                if (booltest)
                {
                    if (NewArryRow == 5)
                    {
                        dg5.ColumnCount = NewArryRow;
                        for (int i = 0; i < NewArryRow; i++)
                        {
                            string[] temp_array = new string[NewArryRow];
                            for (int j = 0; j < NewArryRow; j++)
                            {
                                temp_array[j] = NewArry[i, j].ToString();
                            }
                            dg5.Rows.Add(temp_array);
                        }
                    }
                    if (NewArryRow == 4)
                    {
                        dg4.ColumnCount = NewArryRow;
                        for (int i = 0; i < NewArryRow; i++)
                        {
                            string[] temp_array = new string[NewArryRow];
                            for (int j = 0; j < NewArryRow; j++)
                            {
                                temp_array[j] = NewArry[i, j].ToString();
                            }
                            dg4.Rows.Add(temp_array);
                        }
                    }
                    if (NewArryRow == 3)
                    {
                        dg3.ColumnCount = NewArryRow;
                        for (int i = 0; i < NewArryRow; i++)
                        {
                            string[] temp_array = new string[NewArryRow];
                            for (int j = 0; j < NewArryRow; j++)
                            {
                                temp_array[j] = NewArry[i, j].ToString();
                            }
                            dg3.Rows.Add(temp_array);
                        }
                    }
                    if (NewArryRow == 2)
                    {
                        dg2.ColumnCount = NewArryRow;
                        for (int i = 0; i < NewArryRow; i++)
                        {
                            string[] temp_array = new string[NewArryRow];
                            for (int j = 0; j < NewArryRow; j++)
                            {
                                temp_array[j] = NewArry[i, j].ToString();
                            }
                            dg2.Rows.Add(temp_array);
                        }
                    }
                }


               // MessageBox.Show("루프 횟수 : " + FuncLoop.ToString());
                //=====================

                #endregion
                Fnc_ArrayZero2(NewArry);
            } // if (NewArryRow > 0)
        }

        private void ArryMaxVal(double[,] loop_array, out int[] max_value, out double temp_maxvalue )
        {
            // ,배열내 최대값 찾기
            max_value = new int[2];
            int Loop = (int)Math.Sqrt(loop_array.Length);
            int temp_i = -1;
            int temp_j = -1;

            temp_maxvalue= -999;

            for (int i = 0; i < Loop; i++)
            {
                for (int j = i + 1; j < Loop; j++)
                {
                    if (temp_maxvalue < loop_array[i, j])
                    {
                        temp_i = i;
                        temp_j = j;
                        temp_maxvalue = loop_array[i, j];
                    }
                }
            }
            max_value[0] = temp_i;
            max_value[1] = temp_j;
        }

        #region == 정적변수 AnalyStr 분리후 DBF_Alany-ACluster--AnalyIndx  ==
        public string[] SplitStr(string Str)
        {
            Str = Str.Replace("o", "");
            string[] ReVal = Str.Split('/');
            return ReVal;
        }
        #endregion




    }
}
